home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- CDragAcrossTask.c
-
- AUTHOR: Andrew_Gilmartin@Brown.Edu
- MODIFIED: 93-11-04
-
- This global mouse task is used in conjunction with a CDragAcrossTable to
- provide the user feedback while selecting the boundaries along which to
- move the selected cells or place a new object/cell.
-
- Copyright (C) 1993 by Brown University. All rights reserved.
-
- Permission is granted to any individual or institution to use, copy,
- or redistribute the binary version of this software and its
- documentation provided this notice and the copyright notices are
- retained. Permission is granted to any individual or non-profit
- institution to use, copy, modify, or redistribute the source files
- of this software provided this notice and the copyright notices are
- retained. This software may not be distributed for profit, either
- in original form or in derivative works, nor can the source be
- distributed to other than an individual or a non-profit institution.
- Any individual or group interested in seeing and/or using these
- source files but who are prevented from doing so by the above
- constraints should contact Don Wolfe, Vice-President for Computer
- Systems at Brown University, (401) 863-7247, for possible
- software licensing of the source developed at Brown.
-
- Brown University and Andrew James Gilmartin make no representations
- about the suitability of this software for any purpose.
-
- BROWN UNIVERSITY AND ANDREW JAMES GILMARTIN GIVE NO WARRANTY, EITHER
- EXPRESS OR IMPLIED, FOR THE PROGRAM AND/OR DOCUMENTATION PROVIDED,
- INCLUDING, WITHOUT LIMITATION, WARRANTY OF MERCHANTABILITY AND
- WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE.
-
- ******************************************************************************/
-
- #include "ForgetRgn.h"
- #include "CDragAcrossTable.h"
- #include "CDragAcrossTask.h"
-
-
-
- /******************************************************************************
- IDragTable
-
- Initialize the task.
- ******************************************************************************/
-
- void CDragAcrossTask::IDragAcrossTask
- ( CDragAcrossTable* aTable
- , RgnHandle aSelectionRgn
- , short aNameIndex )
- {
- IGlobalMouseTask( aNameIndex );
-
- itsFromTable = itsToTable = aTable;
-
- itsSelectionRgn = aSelectionRgn;
- isSelectionRgnVisible = FALSE;
-
- } /* IDragAcrossTask */
-
-
-
- /******************************************************************************
- Dispose
-
- Dispose of the drag region and then the rest.
- ******************************************************************************/
-
- void CDragAcrossTask::Dispose( void )
- {
- ForgetRgn( itsSelectionRgn );
-
- inherited::Dispose();
-
- } /* Dispose */
-
-
-
- /******************************************************************************
- BeginTracking
-
- Begin tracking the mouse.
- ******************************************************************************/
-
- void CDragAcrossTask::BeginTracking( Point startPt )
- {
- Boundary hitBoundaries;
-
- FindHitBoundaries( itsFromTable, startPt, &hitBoundaries );
- itsToBoundaries = hitBoundaries;
-
- itsToTable->Prepare();
- itsToTable->SelectBoundaries( itsToBoundaries );
- DrawSelectionRgn( TRUE );
-
- } /* BeginTracking */
-
-
-
- /******************************************************************************
- KeepTracking
-
- The code here is a mixture of screen updating and hit finding. The logical
- sequence is
-
- hide the selection region,
- deselect the previous boundaries,
- find the hit table,
- find the hit boundaries,
- select the current boundaries, and then
- draw the selection region.
-
- However, following this sequence in order does a log of drawing and makes
- for a very flickering screen. So the logical sequence is coded to minimize
- the amount of screen redraw. It does work but it is really ugly.
- ******************************************************************************/
-
- void CDragAcrossTask::KeepTracking( Point currPt, Point prevPt, Point startPt )
- {
- CDragAcrossTable* hitTable;
- Boundary hitBoundaries;
- Boolean hideBoundary;
- Boolean showBoundary;
- Boolean moveSelection;
- Boolean hideSelection;
- Boolean showSelection;
- Boolean autoScrolled;
-
- /* Do we have to un-draw the previous boundaries? */
-
- hitTable = FindHitTable( currPt );
- if ( hitTable )
- {
- FindHitBoundaries( hitTable, currPt, &hitBoundaries );
- autoScrolled = AutoScroll( hitTable, currPt );
- }
- else
- {
- hitBoundaries = kEmptyBoundary;
- }
-
- /* Figure out what needs to be drawn */
-
- hideBoundary = itsToTable != NULL && itsToTable != hitTable;
- showBoundary = hitTable != NULL
- && ( itsToTable != hitTable || ! EqualPt( itsToBoundaries, hitBoundaries ) );
-
- moveSelection = ! EqualPt( currPt, prevPt );
- hideSelection = moveSelection || showBoundary || hideBoundary;
- showSelection = autoScrolled || ! hideSelection;
-
- if ( hideSelection )
- DrawSelectionRgn( FALSE );
-
- if ( hideBoundary )
- {
- itsToTable->Prepare();
- itsToTable->SelectBoundaries( kEmptyBoundary );
- }
-
- if ( showBoundary )
- {
- hitTable->Prepare();
- hitTable->SelectBoundaries( hitBoundaries );
- }
-
- if ( moveSelection )
- OffsetRgn( itsSelectionRgn, currPt.h - prevPt.h, currPt.v - prevPt.v );
-
- if ( showSelection )
- DrawSelectionRgn( TRUE );
-
- itsToTable = hitTable;
- itsToBoundaries = hitBoundaries;
-
- // if ( autoScrolled )
- // {
- // long ticks;
- // Delay( PAGE_DELAY, &ticks );
- // }
-
- } /* KeepTracking */
-
-
-
- /******************************************************************************
- EndTracking
-
- Notify the CDragAcrossTable should the user have selected a boundary.
- ******************************************************************************/
-
- void CDragAcrossTask::EndTracking( Point currPt, Point prevPt, Point startPt )
- {
- /* Hide and dispose of the selection region */
-
- DrawSelectionRgn( FALSE );
-
- if ( itsToTable != NULL )
- {
- itsToTable->SelectBoundaries( kEmptyBoundary );
- itsFromTable->MoveSelection( itsToTable, itsToBoundaries );
- }
-
- } /* EndTracking */
-
-
-
- /******************************************************************************
- DrawSelectionRgn
-
- Draw the selection region. Since this method is used to both show and hide
- the region, isSelectionRgnVisible keeps track of when the region should
- really be draw.
- ******************************************************************************/
-
- void CDragAcrossTask::DrawSelectionRgn( Boolean showRgn )
- {
- /* Is the visability changing? */
-
- if ( isSelectionRgnVisible != showRgn )
- {
- PenState penState;
-
- /* Draw on the desktop */
-
- gDesktop->Prepare();
-
- GetPenState( &penState );
-
- PenPat( gray );
- PenMode( srcXor );
- FrameRgn( itsSelectionRgn );
-
- SetPenState( &penState );
-
- /* Remember its visability */
-
- isSelectionRgnVisible = showRgn;
- }
-
- } /* DrawSelectionRgn */
-
-
-
- /******************************************************************************
- FindHitTable
-
- Finding the drag table is similar to dispatching the cursor. Infact, the
- code below is taken from DispatchCursor() and friends. Given a point in
- global coordinates first find the enclosing window and then find the
- sub-view that is a CDragAcrossTable.
-
- (There should be some means of finding not just a CDragAcrossTable, but a
- particular subclass. This could be done by keeping a list of tables to
- check. At the end of FindHitTable() it would check that the table found
- is amoung the listed tables.)
- ******************************************************************************/
-
- CDragAcrossTable* CDragAcrossTask::FindHitTable( Point mousePt )
- {
- WindowPtr macWindow;
- CView* hitView;
-
- /* Which Macintosh window? */
-
- if ( FindWindow( mousePt, &macWindow ) != inContent )
- return NULL;
-
- /* Is it a TCL window? */
-
- if ( ((WindowPeek) macWindow)->windowKind != OBJ_WINDOW_KIND )
- return NULL;
-
- /* Find sub-view that is a CDragAcrossTable */
-
- hitView = (CWindow*) GetWRefCon( macWindow );
-
- hitView->Prepare(); // Use Window's port and coords
- GlobalToLocal( &mousePt ); // Convert mouse location in event
-
- do
- {
- hitView = hitView->FindSubview(mousePt);
-
- } while ( hitView != NULL && ! member( hitView, CDragAcrossTable ) );
-
- /* Done */
-
- return (CDragAcrossTable*) hitView;
-
- } /* FindHitTable */
-
-
-
- /******************************************************************************
- FindHitBoundaries
-
- A utility method to convert the given point from global to the table's
- local coordinates and return info on the boundaries hit.
- ******************************************************************************/
-
- void CDragAcrossTask::FindHitBoundaries
- ( CDragAcrossTable* aTable
- , Point hitPt
- , Boundary* hitBoundary )
- {
- LongPt tablePt;
-
- aTable->Prepare();
- GlobalToLocal( &hitPt );
- aTable->QDToFrame( hitPt, &tablePt );
-
- aTable->FindBoundaries( &tablePt, hitBoundary );
-
- } /* FindHitBoundaries */
-
-
-
- /******************************************************************************
- AutoScroll
-
- A utility method to convert the given point from global to the table's
- local coordinates and auto-scroll if necessary. The selection region is
- hidden if scrolling is to occure.
- ******************************************************************************/
-
- Boolean CDragAcrossTask::AutoScroll( CDragAcrossTable* aTable, Point hitPt )
- {
- LongPt tablePt;
-
- aTable->Prepare();
- GlobalToLocal( &hitPt );
- aTable->QDToFrame( hitPt, &tablePt );
-
- if ( aTable->ShouldScroll( &tablePt, NULL ) )
- {
- DrawSelectionRgn( FALSE );
- return aTable->AutoScroll( &tablePt );
- }
-
- return FALSE;
-
- } /* AutoScroll */
-
-
-
-